#ifndef CGTHREADPOOLWRAPPER_H
#define CGTHREADPOOLWRAPPER_H

class CGThreadPoolProcess
{ 
friend class CGThreadPoolWrapper;
public:
  CGThreadPoolProcess()
  {
    m_eventRunning.Create(FALSE, FALSE);
    m_eventStopped.Create(FALSE, FALSE);
    m_running = FALSE;
  }
  virtual ~CGThreadPoolProcess()
  {
  }
 
  virtual gulong RunProcess() = 0;
  virtual gboolean StopProcess()
  {
    m_running = FALSE;
    return TRUE;
  }

protected:
  CGEventWrapper m_eventRunning;  /* event when process start running */
  CGEventWrapper m_eventStopped;  /* event when process stops running */
  gboolean m_running;
};

typedef std::list<CGThreadPoolProcess *> GThreadPoolProcessList;
typedef GThreadPoolProcessList::iterator GThreadPoolProcessIt;

class CGThreadPoolWrapper
{
 public:
  CGThreadPoolWrapper(const gchar *name);
  virtual ~CGThreadPoolWrapper();

  gboolean CreatePool(gint maxThreads, gboolean exclussive);
  gboolean DestroyPool(gboolean immediate, gboolean wait);
  gboolean Submit(CGThreadPoolProcess *process, gboolean push);
  gboolean Push(); /* submitted processes not pushed */
  glong GetNumSubmitThreads() { return (glong) m_submitThreads.size(); }
  glong GetNumPushedThreads() { return (glong) m_pushedThreads.size(); }
  glong GetNumRunnigThreads() { return (glong) m_runningThreads.size(); }
  glong GetNumDoneThreads() { return (glong) m_doneThreads.size(); }
  gboolean WaitRunningDone(gulong milis = WAIT_INFINITE); /* wait for running list was empty */

protected:
  static void ThreadPoolProc(gpointer userData, gpointer params);
  gboolean Push(CGThreadPoolProcess *process);

protected:
  GThreadPool *m_threadPool;
  gchar *m_name;
  GThreadPoolProcessList m_submitThreads;	//!< jobs submitted
  GThreadPoolProcessList m_pushedThreads;	//!< jobs pushed
  GThreadPoolProcessList m_runningThreads;	//!< jobs running
  GThreadPoolProcessList m_doneThreads;		//!< jobs done
  CGCriticalSectionWrapper m_threadsCS;		//!< access all list
};

#endif // CGTHREADPOOLWRAPPER_H
